from flask import current_app
from flask import g, jsonify
from flask import redirect
from flask import render_template
from flask import request
from flask import session
from app import constants
from app import user_login_data, db
from app.models import Category
from app.modules.profile import profile_blu
from app.utils.image_storage import pic_storage
from app.utils.response_code import RET

"""
个人中心页面:
    1. 获取当前用户登录信息
    2. 返回模型中指定内容(个人中心页面)
    3. 页面中的功能(基本资料/头像设置等,都需要局部刷新,这里采用ajax交互)
127.0.0.1:5000/user/info
"""
@profile_blu.route('/info')
@user_login_data
def get_user_info():
    user = g.user
    if not user:
        # 重定向到主页
        return redirect('/')
    data = {
        "user_info": user.to_dict()
    }
    # 渲染模板
    return render_template("profile/user.html", data=data)


"""
个人基本资料展示:
    1. 进入界面之后展示用户的基本资料(个性签名/昵称/性别)
    2. 用户修改之后点击保存向服务器发起请求进行数据保存更新
"""
@profile_blu.route('/user_info', methods=['POST', 'GET'])
@user_login_data
def base_info():
    """
    :param nick_name, type: string
    :param signature, type: string
    :param gender, type:string
    传入参数类型:json
    :return: {"errno": errno, "errmsg": errmsg}
    """
    if not g.user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    if request.method == "GET":
        data = {
            "user_info": g.user.to_dict()
        }
        return render_template("profile/user_base_info.html", data=data)

    nick_name = request.json.get("nick_name", "")
    gender = request.json.get("gender", "")
    signature = request.json.get("signature", "")
    if not all([nick_name, gender, signature]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数有误")
    if gender not in ['MAN', "WOMAN"]:
        return jsonify(errno=RET.PARAMERR, errmsg="性别有误")
    # 更新保存数据
    g.user.gender = gender
    g.user.nick_name = nick_name
    g.user.signature = signature
    # 将session中保存的数据进行实时更新,为什么只有nick_name? TODO
    session['nick_name'] = nick_name
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存数据失败")
    return jsonify(errno=RET.OK, errmsg="更新成功")


"""
用户头像上传:
    1. 用户可以进行头像的修改,上传完毕之后更新个人中心跟头像相关的标签内容
    2. 上传的头像文件保存到七牛云提供的文件存储服务器中
"""
@profile_blu.route('/pic_info', methods=['GET', "POST"])
@user_login_data
def pic_info():
    """
    :param avatar,type: file, 头像
    :return: {"errno": errno, "errmsg": errmsg}
    """
    if request.method == "GET":
        return render_template("profile/user_pic_info.html", data={"user_info": g.user.to_dict()})
    # 获取上传的文件
    try:
        avatar_file = request.files.get("avatar").read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="读取文件出错")
    # 再将文件上传到七牛云
    print(avatar_file)
    try:
        url = pic_storage(avatar_file)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="上传图片错误")
    # 将头像信息更新到当前和用户的模型中
    # 设置用户模型的相关数据
    g.user.avatar_url = url
    print(url)
    # 将数据保存到数据库
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存用户数据错误")

    return jsonify(errno=RET.OK, errmsg="OK", data={"avatar_url": constants.QINIU_DOMIN_PREFIX+url})

@profile_blu.route("/pass_info", methods=["GET", "POST"])
@user_login_data
def pass_info():
    """
    :param old_password type:string
    :param new_password type:string
    :return: {"errno": errno, "errmsg": errmsg}
    """
    if request.method == "GET":
        return render_template("profile/user_pass_info.html")

    old_password = request.json.get("old_password")
    new_password = request.json.get("new_password")

    if not all([old_password, new_password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数有误")

    if not g.user.check_password(old_password):
        return jsonify(errno=RET.PWDERR, errmsg="原密码错误")
    g.user.password = new_password

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存数据失败")

    return jsonify(errno=RET.OK, errmsg="密码修改成功")


"""
用户新闻收藏:
    1. 使用分页形式展示用户锁收藏的新闻
    2. 可以使用url的查询字符串传入不同的页数进行模板渲染不同的数据
    3. 可以直接使用模板显示,也可以使用ajax进行请求
127.0.0.1:5000/user/colection?p=页码
"""
@profile_blu.route('/collection')
@user_login_data
def user_collection():
    """

    :return: 总页数  当前页数
    """
    # 获取页数,默认第一页
    p = request.args.get("p", 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="参数内容错误")
    news_collections = []
    current_page = 1
    total_page = 1
    if g.user:
        try:
            paginate = g.user.collection_news.paginate(p, constants.USER_COLLECTION_MAX_NEWS, False)
            # 当前页码所有数据
            news_collections = paginate.items
            # 当前页码
            current_page = paginate.page
            # 总页数
            total_page = paginate.pages
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="")
    # 对象列表转字典列表
    news_dict_collections = []
    for news in news_collections if news_collections else []:
        news_dict_collections.append(news.to_basic_dict())

    data = {
        "collections": news_dict_collections,
        "current_page": current_page,
        "total_page": total_page
    }

    return render_template("profile/user_collection.html", data=data)


"""
用户发布新闻:
    1. 用户可以在个人中心发布新闻
    2. 发布完毕新闻需要通过审核才能显示
    3. 用户发布完毕新闻跳转到用户新闻列表
    4. 后台管理员对新闻进行审核
    5. 如果某条新闻是用户发布的,那么在新闻详情页展示该用户的个人资料
    6. 需要更新新闻查询调教,添加status == 0 (已审核通过)

"""
@profile_blu.route('news_release')
@user_login_data
def news_release():
    categories = []
    try:
        # 获取所有的分类数据,只是获取分类类名,莫想多了
        categories = Category.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询失败")

    # 定义列表保存分类数据
    categories_dict = []
    for category in categories if categories else None:
        categories_dict.append(category.to_dict())

    # 移除"最新分类"
    categories_dict.pop(0)
    # 渲染模板
    return render_template("profile/user_news_release.html", data={"categories": categories_dict})

